package com.douqu.game.battle.entity;

import com.douqu.game.battle.server.GameServer;
import com.douqu.game.core.e.E_SkillType;
import com.douqu.game.core.entity.battle.BattleAObject;
import com.douqu.game.core.entity.battle.BattleSkill;
import com.douqu.game.core.entity.battle.Position;
import com.douqu.game.core.entity.battle.SpriteBattleTmp;
import com.douqu.game.core.entity.sprite.Card;
import com.douqu.game.core.entity.sprite.CardLv;
import com.douqu.game.core.entity.sprite.CardQuality;
import com.douqu.game.core.entity.sprite.Soldier;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.core.protobuf.SGWarProto;
import org.apache.log4j.Logger;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created by bean on 2017/9/13.
 */
public class MonsterBattleTmp extends SpriteBattleTmp {

    Logger logger = Logger.getLogger(MonsterBattleTmp.class);


    @Override
    public boolean checkAI()
    {
        if(spriteController.isPlayer())
            return false;

        if(GameServer.TEST && soldierList.size() > 0)
        {
            //测试时只出一个兵
//            logger.info("AI已经出兵:" + soldierList.size());
            return false;
        }

        //对手场上的兵
        List<BattleAObject> list = targetBattleTmp.getSoldierList();

        if(list.size() > 0)
        {
            logger.info(spriteController.getName() + " team:" + teamNo + " 开始检测AI出牌");

            Card restrictTo = null, restrictToMe = null;
            DataFactory dataFactory = DataFactory.getInstance();
            Soldier soldier = null;
            Soldier targetSoldier = null;
            choose:for(Card card : cardList)
            {
                soldier = dataFactory.getGameObject(DataFactory.SOLDIER_KEY, card.soldierId);
                for(BattleAObject ba : list)
                {
                    if(ba.isDie())
                    {
                        logger.info(ba.getId()+" 已经死亡 ");
                        continue;
                    }

                    if(restrictTo != null && restrictToMe != null)
                        break choose;

                    targetSoldier = ((BattleSoldierAObject) ba).getSoldier();
                    if(soldier.isRestrict(targetSoldier))
                    {
//                        logger.info("检查到克制关系,再检测水晶是否够:当前水晶:" + curCrystal+" 需要的水晶:" + card.crystal);
                        //被我克制
                        restrictTo = card;
                    }

                    if(!targetSoldier.isRestrict(soldier))
                    {
//                        logger.info("检查到对方对我的克制关系,再检测水晶是否够:当前水晶:" + curCrystal+" 需要的水晶:" + card.crystal);
                        restrictToMe = card;
                    }
                }
            }
            logger.info("restrictTo:" + restrictTo + "  restrictToMe:" + restrictToMe);
            //若没克制关系，则出战力最高的兵放在中间的路线
            Card result = null;
            if(restrictTo == null)
            {
                result = restrictToMe == null ? getMaxFCCard() : restrictToMe;
            }
            else
            {
                result = restrictTo;
            }

            if(result != null)
            {
                logger.info("当前水晶:" + curCrystal + " 需要水晶:" + result.crystal);
                result = GameServer.TEST_AI ? result : (curCrystal >= result.crystal ? result : null);
            }

            logger.info("result:" + result);
            if(result != null)
            {
                //兵种上场
                soldierBorn(result, null);
            }
            else
            {
                return false;
            }
        }
        else
        {
            if(isMaxCrystal())
            {
                BattleMasterAObject masterAObject = (BattleMasterAObject) masterSoldier;
                long currentTime = System.currentTimeMillis();
                //检测是否主将技能是否可以释放（CD时间是否到了）
                BattleSkill skill = masterAObject.getReleaseSkill(currentTime);
                if(skill != null)
                {
                    //技能选择目标规则
                    BattleAObject target = null;
                    E_SkillType hpType = skill.getSkill().getType();
                    if (hpType == E_SkillType.HP_ADD) {
                        if (skill.getSkill().effectTargetType == ConstantFactory.TARGET_TYPE_PARTNER) {
                            // 1.己方增益->治疗->己方损失血量最多的单位
                            BattleAObject temp = getMaxLossHPSoldier();
                            if (temp == null)
                                target = masterAObject;
                            else
                                target = temp.getLossHp() < masterSoldier.getLossHp() ? masterAObject : temp;

                            if (target.getLossHp() == 0)
                                target = null;
                        }
                    } else if (hpType == E_SkillType.HP_SUB) {
                        if (skill.getSkill().effectTargetType == ConstantFactory.TARGET_TYPE_ENEMY) {
                            // 2.敌方减益->对方场上是否有兵->有->敌方战力最高的兵
                            //                          ->无->敌方主将
                            target = targetBattleTmp.getMaxFCSoldier();
                            target = target == null ? targetBattleTmp.getMasterSoldier() : target;
                        }
                    } else if (hpType == E_SkillType.ATT_ADD) {
                        //          ->增强->己方战力最高的单位
                        target = getMaxFCSoldier();
                    } else if (hpType == E_SkillType.ATT_SUB) {

                    }

                    if (target != null)
                    {
                        logger.info(getTeamNo() + " AI 释放主将技能! 目标:" + target);
                        skill.release(target.getPosition(), GameServer.currentTime, target);
                        addCrystal(-skill.getSkill().crystal);
                    }
                }
                else
                {
                    //若无，则出战力最强的兵，放在中间路线
                    logger.info("出战力最强的兵，放在中间路线");
                    Card card = getMaxFCCard();
                    if(card != null)
                    {
                        soldierBorn(card, null);
                    }
                }

            }
            else
            {
                return false;
            }
        }

        return true;
    }


    /**
     * 小兵出生
     * @param card
     */
    public void soldierBorn(Card card, List<SGCommonProto.Pos> posList)
    {
        Soldier soldier = DataFactory.getInstance().getGameObject(DataFactory.SOLDIER_KEY, card.soldierId);
        if(soldier == null)
            return;

        battleController.checkStar(this, soldier.race);

        addCrystal(-card.crystal);
        toBattlefield(card);

        BattleSoldierAObject battleSoldierAObject = null;
        SGCommonProto.BattleSoldier.Builder soldierData = null;

        //转发消息
        SGWarProto.S2C_ToBattle.Builder response = SGWarProto.S2C_ToBattle.newBuilder();
//        response.setPlayerIndex(spriteController.getObjectIndex());
        response.setCardId(card.getId());

        List<BattleAObject> sendList = new CopyOnWriteArrayList<>();
        CardLv lv = DataFactory.getInstance().getGameObject(DataFactory.CARD_LV_KEY,card.lv);
        CardQuality cardQuality = lv.getByQuality(card.quality);
        for(int i = 0; i < card.soldierCount; i++)
        {
            battleSoldierAObject = new BattleSoldierAObject(spriteController, soldier, cardQuality.fc, battleController.getSoldierUniqueId());
            if(posList == null)
                battleSoldierAObject.setPosition(battleController.getMiddlePos(teamNo));
            else
                battleSoldierAObject.setPosition(new Position(posList.get(i)));
            addBattleSoldier(battleSoldierAObject);
            battleController.addSoldier(battleSoldierAObject);

            soldierData = SGCommonProto.BattleSoldier.newBuilder();
            soldierData.setUniqueId(battleSoldierAObject.getId());
            soldierData.setSoldierId(soldier.getId());
            soldierData.setMaxHP(battleSoldierAObject.getMaxHp());
            soldierData.setPos(battleSoldierAObject.getPosition().parsePos());
            soldierData.setTeamNo(battleSoldierAObject.getTeamNo());
            response.addSoldier(soldierData);

            sendList.add(battleSoldierAObject);
        }

        logger.info("ToBattle:" + response + " soldier:" + soldier);
        battleController.dispatchMsg(SGMainProto.E_MSG_ID.MsgID_War_ToBattle_VALUE, response.build().toByteArray());

        for(BattleAObject battleAObject : sendList)
        {
            battleAObject.checkBornSkill();
        }

        int targetSoldierSize = targetBattleTmp.getSoldierList().size();
        if(targetSoldierSize == 0)
        {
            BattleAObject targetMaster = targetBattleTmp.getMasterSoldier();
            for(BattleAObject battleAObject : sendList)
            {
                battleAObject.checkRoute(targetMaster);
            }
        }
    }

}
